package com.smart.community.commons.base;

import com.baomidou.mybatisplus.extension.service.IService;
import com.smart.community.commons.result.PageResult;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

/**
 * 基础Service接口
 * 继承MyBatis-Plus的IService接口，并提供扩展方法
 * 所有业务Service接口都应该继承此接口
 * 
 * @author Wu.Liang
 * @version 1.0.0
 * @since 2024-12-19
 * @param <T> 实体类型
 */
public interface IBaseService<T extends BaseEntity> extends IService<T> {
    
    // ========================= 条件查询 =========================
    
    /**
     * 根据条件查询实体列表
     * 
     * @param query 查询条件
     * @return 实体列表
     */
    List<T> listByQuery(BaseQuery query);
    
    /**
     * 根据条件查询单个实体
     * 
     * @param query 查询条件
     * @return 实体对象
     */
    T getOneByQuery(BaseQuery query);
    
    /**
     * 根据条件查询单个实体，如果不存在则抛出异常
     * 
     * @param query 查询条件
     * @return 实体对象
     * @throws RuntimeException 当实体不存在时
     */
    T getOneThrowIfNotFound(BaseQuery query);
    
    /**
     * 根据条件查询第一个实体
     * 
     * @param query 查询条件
     * @return 实体对象
     */
    T getFirstByQuery(BaseQuery query);
    
    /**
     * 根据条件查询实体数量
     * 
     * @param query 查询条件
     * @return 数量
     */
    long countByQuery(BaseQuery query);
    
    /**
     * 根据条件判断是否存在实体
     * 
     * @param query 查询条件
     * @return 是否存在
     */
    boolean existsByQuery(BaseQuery query);
    
    // ========================= 分页查询 =========================
    
    /**
     * 分页查询实体
     * 
     * @param current 当前页码
     * @param size    每页大小
     * @return 分页结果
     */
    PageResult<T> pageQuery(Integer current, Integer size);
    
    /**
     * 分页查询实体
     * 
     * @param current 当前页码
     * @param size    每页大小
     * @param query   查询条件
     * @return 分页结果
     */
    PageResult<T> pageQuery(Integer current, Integer size, BaseQuery query);
    
    /**
     * 分页查询实体
     * 
     * @param query 查询条件（包含分页参数）
     * @return 分页结果
     */
    PageResult<T> pageQuery(BaseQuery query);
    
    // ========================= 扩展方法 =========================
    
    /**
     * 根据ID查询实体，如果不存在则抛出异常
     * 
     * @param id 主键ID
     * @return 实体对象
     * @throws RuntimeException 当实体不存在时
     */
    T getByIdThrowIfNotFound(Serializable id);
    
    /**
     * 根据ID判断实体是否存在
     * 
     * @param id 主键ID
     * @return 是否存在
     */
    boolean existsById(Serializable id);
    
    /**
     * 根据条件删除实体（逻辑删除）
     * 
     * @param query 删除条件
     * @return 是否删除成功
     */
    boolean removeByQuery(BaseQuery query);
    
    /**
     * 根据条件物理删除实体
     * 
     * @param query 删除条件
     * @return 是否删除成功
     */
    boolean deleteByQuery(BaseQuery query);
    
    /**
     * 根据ID物理删除实体
     * 
     * @param id 主键ID
     * @return 是否删除成功
     */
    boolean deleteById(Serializable id);
    
    /**
     * 根据ID集合批量物理删除实体
     * 
     * @param ids 主键ID集合
     * @return 是否删除成功
     */
    boolean deleteByIds(Collection<? extends Serializable> ids);
    
    // ========================= 缓存操作 =========================
    
    /**
     * 清除指定实体的缓存
     * 
     * @param id 主键ID
     */
    void evictCache(Serializable id);
    
    /**
     * 清除所有缓存
     */
    void evictAllCache();
    
    /**
     * 预热缓存
     */
    void warmUpCache();
}
